package edu.fdzc.project.service.impl;

import com.alibaba.excel.util.IoUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import edu.fdzc.project.config.MinioConfig;
import edu.fdzc.project.entity.Resource;
import edu.fdzc.project.entity.vo.PageVo;
import edu.fdzc.project.service.ResourceService;
import edu.fdzc.project.mapper.ResourceMapper;
import edu.fdzc.project.utils.EncodingUtil;
import edu.fdzc.project.utils.JwtUtil;
import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

/**
* @author zhangjiu
* &#064;description  针对表【resource】的数据库操作Service实现
* @createDate 2025-06-21 17:10:34
*/
@Service
public class ResourceServiceImpl extends ServiceImpl<ResourceMapper, Resource> implements ResourceService{

    @Autowired
    private ResourceMapper resourceMapper;

    @Value("${minio.bucketName}")
    private String bucketName;

    @Value("${kkFileViewServer}")
    private String kkfileviewUrl;

    @Autowired
    private MinioClient minioClient;

    @Override
    public Resource selectById(Long id) {
        return resourceMapper.selectById(id);
    }

    @Override
    public PageVo<Resource> selectPage(Long pageNum, Long pageSize, Resource resource) {
        Long teacherId = JwtUtil.getUserId();
        String name = resource.getName();
        Long categoryId = resource.getCategoryId();

        //查询方式
        LambdaQueryWrapper<Resource> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Resource::getTeacherId, teacherId);
        if(name != null && !name.isEmpty())
        {
            wrapper.like(Resource::getName, name);
        }
        if(categoryId != null)
        {
            wrapper.eq(Resource::getCategoryId, categoryId);
        }
        wrapper.orderByAsc(Resource::getCreateTime);

        //执行
        Page<Resource> res = resourceMapper.selectPage(new Page<>(pageNum, pageSize), wrapper);
        PageVo<Resource> pageVo = new PageVo<>();
        pageVo.setTotal(res.getTotal());
        pageVo.setList(res.getRecords());
        return pageVo;
    }

    @Override
    public Resource upload(MultipartFile file) {
        if(file == null)
        {
            return null;
        }
        String originalFilename = file.getOriginalFilename();//原始文件名
        String newFilename = UUID.randomUUID().toString() + "_" + originalFilename; //新文件名称
        Resource resource = new Resource();
        resource.setName(originalFilename);
        resource.setUrl(newFilename); // 设置url 为新文件的名称

        try {
            InputStream in = file.getInputStream();
            minioClient.putObject(
                    PutObjectArgs.builder().bucket(bucketName).object(newFilename)
                            .stream(in,file.getSize(),-1)
                            .contentType(file.getContentType())
                            .build()
            );
            in.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return resource;
    }

    @Override
    public Integer insert(Resource resource) {
        Long teacherId = JwtUtil.getUserId();
        resource.setTeacherId(teacherId);

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String createTime = LocalDateTime.now().format(formatter);
        resource.setCreateTime(createTime);
        //添加资源
        return resourceMapper.insert(resource);
    }

    @Override
    public Integer updateByResId(Resource resource) {
//        return 0;
        Long teacherId = JwtUtil.getUserId();
        resource.setTeacherId(teacherId);

        //设置时间格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String updateTime = LocalDateTime.now().format(formatter);
        resource.setUpdateTime(updateTime);

        return resourceMapper.updateById(resource);
    }

    @Override
    public void download(HttpServletResponse response, Long id) {
        Resource resource = resourceMapper.selectById(id);
        String fileName = resource.getUrl();
        String originalFilename = resource.getName();
        InputStream in = null;

        try {
            StatObjectResponse stat = minioClient.statObject(
                    StatObjectArgs.builder().bucket(bucketName).object(fileName).build());
            response.setContentType( stat.contentType() + "; charset=utf-8");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(originalFilename, StandardCharsets.UTF_8));

            //文件下载
            in = minioClient.getObject(
                    GetObjectArgs.builder().bucket(bucketName).object(fileName).build());
            IoUtils.copy(in,response.getOutputStream());
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if(in != null)
            {
                try {
                    in.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    @Override
    public String getPreviewUrl(Long id) {
        Resource resource = resourceMapper.selectById(id);
        String url = null;
        if(resource != null)
        {
            String filename = resource.getUrl();
            try {
                url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs
                        .builder()
                        .bucket(bucketName)
                        .object(filename)
                        .method(Method.GET)
                        .build());
                System.out.println(url);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

            try {
                url = EncodingUtil.base64AndUrlEncode(url);
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
            url = kkfileviewUrl + url;
        }
        return url;
    }

    @Override
    public Integer deleteById(Long id) {
        //resourceId
        return resourceMapper.deleteById(id);
    }
}




